package com.jin.Logic;

import com.jin.Exception.http.ForbiddenException;
import com.jin.Exception.http.ParameterException;
import com.jin.bo.SkuOrderBO;
import com.jin.core.enumeration.CouponType;
import com.jin.core.money.IMoneyDiscount;
import com.jin.model.Coupon;
import com.jin.model.UserCoupon;
import com.jin.util.CommonUtil;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


public class CouponChecker {
    private Coupon coupon;

    private IMoneyDiscount iMoneyDiscount;
    public CouponChecker(Coupon coupon,IMoneyDiscount iMoneyDiscount) {
        this.coupon = coupon;
        this.iMoneyDiscount = iMoneyDiscount;
    }

    //检测一下优惠券是否过期
    public void isOk(){
        Date now = new Date();
        Boolean isInTimeline = CommonUtil.isInTimeLine(now,coupon.getStartTime(),coupon.getEndTime());
        if (!isInTimeline){
            throw new ForbiddenException(40007);
        }
    }

    //计算价格,判断最终的价格是否一致
    public void finalTotalPriceIsOk(BigDecimal orderFinalTotalPrice,
                                    BigDecimal serverTotalPrice){
        BigDecimal serverFinalTotalPrice;
        switch (CouponType.toType(coupon.getType())){
            case FULL_MINUS:
            case NO_THRESHOLD_MINUS:
                serverFinalTotalPrice = serverTotalPrice.subtract(coupon.getMinus());
                //最终价<=0都不行
                if (serverFinalTotalPrice.compareTo(new BigDecimal("0"))<=0){
                    throw new ForbiddenException(50008);
                }
                break;
            case FULL_OFF:
                serverFinalTotalPrice = iMoneyDiscount.discount(serverTotalPrice,coupon.getRate());
                break;
            default:
                throw new ParameterException(40009);
        }
        int compare = serverFinalTotalPrice.compareTo(orderFinalTotalPrice);
        if (compare!=0){
            throw new ForbiddenException(50008);
        }
    }

    //当前的优惠券是否真的能被使用
    public void canBeUsed(List<SkuOrderBO> skuOrderBOList,BigDecimal serverTotalPrice){
        BigDecimal orderCategoryPrice;

        if (coupon.getWholeStore()){
            orderCategoryPrice = serverTotalPrice;
        }
        else {
            List<Long> cidList = coupon.getCategoryList()
                    .stream()
                    //Category::getId 牛逼
                    .map(c->c.getId())
                    .collect(Collectors.toList());
            orderCategoryPrice = getSumByCategoryList(skuOrderBOList,cidList);
        }
        couponCanBeUsed(orderCategoryPrice);
    }

    //对满减券进行校验
    private void couponCanBeUsed(BigDecimal orderCategoryPrice){
        switch (CouponType.toType(coupon.getType())){
            case FULL_OFF:
            case FULL_MINUS:
                int compare = coupon.getFullMoney().compareTo(orderCategoryPrice);
                //没有达到门槛
                if (compare>0){
                    throw new ParameterException(40008);
                }
                break;
            case NO_THRESHOLD_MINUS:
                break;
            default:
                throw new ParameterException(40009);
        }
    }

    //求多个分类的总价
    private BigDecimal getSumByCategoryList(List<SkuOrderBO> skuOrderBOList,List<Long> cidList){
        BigDecimal sum = cidList.stream()
                //把每一个id换成price
                .map(cid->getSumByCategory(skuOrderBOList,cid))
                .reduce(BigDecimal::add)
                .orElse(new BigDecimal("0"));
        return sum;
    }


    //求一个分类下的所有sku价钱总和,第二层的for循环
    private BigDecimal getSumByCategory(List<SkuOrderBO> skuOrderBOList,Long cid){
        BigDecimal sum = skuOrderBOList.stream()
                .filter(sku->sku.getCategoryId().equals(cid))
                //用map对每一个元素进行操作
                .map(bo->bo.getTotalPrice())
                //累加
                .reduce(BigDecimal::add)
                .orElse(new BigDecimal("0"));
        return sum;

    }
}
